<?php

namespace Kangcg\WeChat;

use Kangcg\Application\Base\Event;
use Kangcg\Application\Validate\Rules\Url;
use Kangcg\WeChat\Behavior\WeComBehavior;
use Kangcg\WeChat\Library\Urls;
use Kangcg\WeChat\Library\WeChatTrait;
use Kangcg\WeChat\Library\WeCom\User;

/**
 * 企业微信
 * @see url https://developer.work.weixin.qq.com/document/path/90664
 * Class WeChatEnterprise
 * @property string $corpid 企业ID
 * @property string $corpsecret 应用的凭证密钥
 * @property string $access_token 应用的凭证密钥
 * @package Kang\Libs\WeChat
 */
class WeCom extends WeChatTrait
{
    use User;

    const EVENT_AFTER_REFRESH_ACCESS_TOKEN = 'afterRefreshAccessToken';
    const EVENT_BEFORE_REFRESH_ACCESS_TOKEN = 'beforeRefreshAccessToken';
    const EVENT_ACCESS_TOKEN_ERROR = 'REQUEST_ERROR'; //请求错误
    const EVENT_lOG = 'log'; //请求事件

    public function behaviors(): array
    {
        return [
            WeComBehavior::class,
        ];
    }

    //--------------------------通讯录-成员--管理--------------------------------//

    /**
     * https://developer.work.weixin.qq.com/document/path/90195
     * @param array $attributes [
     * 'userid' => 'kcg',
     * 'name' => '康才贵',
     * 'email|mobile' => '051120aaa@163.com',
     * 'department' => [1, 2]
     *
     * ]
     * @return bool
     * @var 成员创建
     */
    public function createUser(array $attributes)
    {
        if (!$this->httpPost(self::USER_CREATE_URL, $attributes, true)) {
            return false;
        }

        return true;
    }

    /**
     * @param array $attributes
     * @return bool
     * @var 成员更新
     */
    public function updateUser(array $attributes)
    {
        if (!$this->httpPost(self::USER_UPDATE_URL, $attributes, true)) {
            return false;
        }

        return true;
    }

    /* @param $userId
     * @return bool
     * @var 成员删除
     */
    public function deleteUser($userId)
    {
        $data['userid'] = $userId;
        if (!$this->httpGet(self::USER_DEL_URL, $data, true)) {
            return false;
        }

        return true;
    }

    /**
     * @param array $useridlist
     * @return bool
     * @var 成员批量删除
     */
    public function deleteBathUser(array $useridlist)
    {
        $data['useridlist'] = $useridlist;
        if (!$this->httpPost(self::USER_BATCH_DEL_URL, $data, true)) {
            return false;
        }

        return true;
    }

    /**
     * $userid 转换为 openid
     * @param string $userid
     * @return bool | string openid
     */
    public function userIdToOpenid($userid)
    {
        $data['userid'] = $userid;
        if (!$result = $this->httpPost(self::USER_ID_TO_OPENID_URL, $data, true)) {
            return false;
        }

        return $result['openid'];
    }

    /**
     * openid 转换为 userid
     * @param string $openid
     * @return bool | string userid
     */
    public function openidToUserId($openid)
    {
        $data['openid'] = $openid;
        if (!$result = $this->httpPost(self::OPENID_TO_USER_ID_URL, $data, true)) {
            return false;
        }

        return $result['userid'];
    }

    /**
     * @param array $user 用户的userid
     * @param array $party 部门ID列表
     * @param array $tag 标签ID列表
     * @return bool
     * @var 批量邀请
     */
    public function userInvite(array $user = [], array $party = [], array $tag = [])
    {
        empty($user) or $data['user'] = $user;
        empty($party) or $data['party'] = $party;
        empty($tag) or $data['tag'] = $tag;

        if (!$this->httpPost(self::USER_BATCH_INVITE_URL, $data, true)) {
            return false;
        }

        return true;
    }

    /**
     * 获取邀请二维码
     * @return bool | string qrcode
     */
    public function userInviteCode()
    {
        if (!$result = $this->httpGet(self::USER_QRCODE_INVITE_URL, null, true)) {
            return false;
        }

        return $result['join_qrcode'];
    }

    /**
     * 通过mobile|email 获取userid
     * @param string $mobile
     * @param string $email
     * @return bool
     */
    public function userGetIdByMobileOrEmai($mobile = '', $email = '')
    {
        $result = false;
        if ($mobile) {
            $result = $this->httpPost(self::USER_ID_GET_URL, ['mobile' => $mobile], true);
        } else if ($email) {
            $result = $this->httpPost(self::USER_ID_GET_EMAIL_URL, ['mobile' => $mobile], true);
        }

        if (!$result) {
            return false;
        }

        return $result['userid'];
    }

    /**
     * @param null $cursor
     * @param int $limit
     * @return bool|array next_cursor dept_user
     */
    public function searchUserId($cursor = null, $limit = 10000)
    {
        $data['cursor'] = $cursor;
        $data['limit'] = $limit;

        if (!$result = $this->httpGet(self::USER_ID_SELECT_URL, $data, true)) {
            return false;
        }

        return $result;
    }
    //--------------------------通讯录-成员--管理--------------------------------//
    //--------------------------通讯录-部门--管理--------------------------------//
    /**
     * @param $name
     * @param integer $parentid 第一个部门 1
     * @param null $order
     * @param null $id
     * @return bool|integer id
     * @var 部门创建
     */
    public function createDepartment($name, $parentid, $order = null, $id = null)
    {
        $data['name'] = $name;
        $data['parentid'] = $parentid;
        $data['order'] = $order;
        $data['id'] = $id;

        if (!$result = $this->httpPost(static::DEPARTMENT_CREATE, $data, true)) {
            return false;
        }

        return $result['id'];
    }

    /**
     * @param $id
     * @param $name
     * @param null $parentid
     * @param null $order
     * @return bool
     * @var 部门更新
     */
    public function updateDepartment($id, $name, $parentid = null, $order = null)
    {
        $data['id'] = $id;
        $data['name'] = $name;
        $data['parentid'] = $parentid;
        $data['order'] = $order;
        if (!$this->httpPost(static::DEPARTMENT_UPDATE, $data, true)) {
            return false;
        }

        return true;
    }

    /**
     * @param $id
     * @return bool
     */
    public function deleteDepartment($id)
    {
        $data['id'] = $id;
        if (!$this->httpGet(static::DEPARTMENT_DELETE, $data, true)) {
            return false;
        }

        return true;
    }

    /**
     * @param null $id
     * @return bool|void
     */
    public function searchDepartment($id = null)
    {
        $data['id'] = $id;
        return $this->httpGet(static::DEPARTMENT_SEARCH, $data, true);
    }

    /**
     * @param $id
     * @return bool|array
     */
    public function detailDepartment($id)
    {
        $data['id'] = $id;
        return $this->httpGet(static::DEPARTMENT_DETAIL, $data, true);
    }
    //--------------------------通讯录-部门--管理--------------------------------//
    //--------------------------通讯录-标签--管理--------------------------------//
    /**
     * @param $tagname
     * @param null $tagid
     * @return bool
     * @var 创建标签
     */
    public function createTag($tagname, $tagid = null)
    {
        $data['tagname'] = $tagname;
        $data['tagid'] = $tagid;
        if (!$result = $this->httpPost(self::TAG_CREATE, $data, true)) {
            return false;
        }

        return $result['tagid'];
    }

    /**
     * @param $tagname
     * @param null $tagid
     * @return bool
     * @var 创建标签
     */
    public function updateTag($tagname, $tagid)
    {
        $data['tagname'] = $tagname;
        $data['tagid'] = $tagid;
        if (!$result = $this->httpPost(self::TAG_UPDATE, $data, true)) {
            return false;
        }

        return true;
    }

    public function deleteTag($tagid)
    {
        $data['tagid'] = $tagid;
        if (!$this->httpGet(self::TAG_DELETE, $data, true)) {
            return false;
        }

        return true;
    }

    /**
     * @param $tagid
     * @return bool|array userlist tagname
     * @var 获取标签成员
     */
    public function searchTagUser($tagid)
    {
        $data['tagid'] = $tagid;
        if (!$result = $this->httpGet(self::TAG_GET_USER, $data, true)) {
            return false;
        }

        return $result;
    }

    /**
     * 增加标签成员
     * @param $tagid 标签ID
     * @param array $userlist 企业成员ID列表，注意：userlist、partylist不能同时为空，单次请求个数不超过1000
     * @param array $partylist 企业部门ID列表，注意：userlist、partylist不能同时为空，单次请求个数不超过100
     * @return bool
     */
    public function addTagUser($tagid, array $userlist = [], array $partylist = [])
    {
        $data['tagid'] = $tagid;
        empty($userlist) or $data['userlist'] = $userlist;
        empty($partylist) or $data['partylist'] = $partylist;

        if (!$this->httpPost(self::TAG_ADD_USER, $data, true)) {
            return false;
        }

        return true;
    }

    /**
     * 删除标签成员
     * @param $tagid 标签ID
     * @param array $userlist 企业成员ID列表，注意：userlist、partylist不能同时为空，单次请求个数不超过1000
     * @param array $partylist 企业部门ID列表，注意：userlist、partylist不能同时为空，单次请求个数不超过100
     * @return bool
     */
    public function deleteTagUser($tagid, array $userlist = [], array $partylist = [])
    {
        $data['tagid'] = $tagid;
        empty($userlist) or $data['userlist'] = $userlist;
        empty($partylist) or $data['partylist'] = $partylist;

        if (!$this->httpPost(self::TAG_DEL_USER, $data, true)) {
            return false;
        }

        return true;
    }

    /**
     * 获取标签列表
     * @return bool | array
     */
    public function searchTag()
    {
        if (!$result = $this->httpGet(self::TAG_SEARCH, null, true)) {
            return false;
        }

        return $result['taglist'];
    }
    //--------------------------通讯录-标签--管理--------------------------------//

    /**
     * @return mixed
     * @var 获取AccessToken
     */
    public function getAccessToken()
    {
        if (!$this->access_token) {
            $this->access_token = $this->refreshAccessToken();
        }

        return $this->access_token;
    }

    public function setAccessToken($accessToken)
    {
        $this->access_token = $accessToken;
        return $this;
    }

    /**
     * @return bool|mixed
     * @var 刷新AccessToken
     */
    public function refreshAccessToken()
    {
        $event = new Event();
        $event->sender = $this;
        $this->trigger(self::EVENT_BEFORE_REFRESH_ACCESS_TOKEN, $event);
        if ($event->handled === true) {
            return $event->data['access_token'] ?? $event->data;
        }

        $data['corpid'] = $this->corpid;
        $data['corpsecret'] = $this->corpsecret;
        $result = $this->httpGet(Urls::COMPANY_GET_TOKEN, $data);
        if (!$result || !isset($result['access_token'])) {
            return false;
        }

        $event->data = $result;
        $this->trigger(self::EVENT_AFTER_REFRESH_ACCESS_TOKEN, $event);
        return $result['access_token'];
    }

    public function getAccessTokenCacheKey()
    {
        return $this->corpid . $this->corpsecret;
    }

    const BASE_URL = 'https://qyapi.weixin.qq.com/';
    const GET_TOKEN = self::BASE_URL . 'cgi-bin/gettoken?';

    const USER_CREATE_URL = self::BASE_URL . 'cgi-bin/user/create?access_token=';
    const USER_UPDATE_URL = self::BASE_URL . 'cgi-bin/user/update?access_token=';
    const USER_FIND_URL = self::BASE_URL . 'cgi-bin/user/get?access_token=';
    const USER_DEL_URL = self::BASE_URL . 'cgi-bin/user/delete?access_token=';
    const USER_BATCH_DEL_URL = self::BASE_URL . 'cgi-bin/user/batchdelete?access_token=';
    const USER_DEP_LIST_URL = self::BASE_URL . 'cgi-bin/user/simplelist?access_token=';
    const USER_LIST_URL = self::BASE_URL . 'cgi-bin/user/list?access_token=';
    const USER_ID_TO_OPENID_URL = self::BASE_URL . 'cgi-bin/user/convert_to_openid?access_token=';
    const OPENID_TO_USER_ID_URL = self::BASE_URL . 'cgi-bin/user/convert_to_userid?access_token=';
    const USER_AUTH_URL = self::BASE_URL . 'cgi-bin/user/authsucc?access_token=';
    const USER_BATCH_INVITE_URL = self::BASE_URL . 'cgi-bin/batch/invite?access_token=';
    const USER_QRCODE_INVITE_URL = self::BASE_URL . 'cgi-bin/corp/get_join_qrcode?access_token=';
    const USER_ID_GET_URL = self::BASE_URL . 'cgi-bin/user/getuserid?access_token=';
    const USER_ID_GET_EMAIL_URL = self::BASE_URL . 'cgi-bin/user/get_userid_by_email?access_token=';
    const USER_ID_SELECT_URL = self::BASE_URL . 'cgi-bin/user/list_id?access_token=';

    const DEPARTMENT_CREATE = self::BASE_URL . 'cgi-bin/department/create?access_token=';
    const DEPARTMENT_UPDATE = self::BASE_URL . 'cgi-bin/department/update?access_token=';
    const DEPARTMENT_DELETE = self::BASE_URL . 'cgi-bin/department/delete?access_token=';
    const DEPARTMENT_SEARCH = self::BASE_URL . 'cgi-bin/department/list?access_token=';
    const DEPARTMENT_DETAIL = self::BASE_URL . 'cgi-bin/department/get?access_token=';

    const TAG_CREATE = self::BASE_URL . 'cgi-bin/tag/create?access_token=';
    const TAG_UPDATE = self::BASE_URL . 'cgi-bin/tag/update?access_token=';
    const TAG_DELETE = self::BASE_URL . 'cgi-bin/tag/delete?access_token=';
    const TAG_GET_USER = self::BASE_URL . 'cgi-bin/tag/get?access_token=';
    const TAG_ADD_USER = self::BASE_URL . 'cgi-bin/tag/addtagusers?access_token=';
    const TAG_DEL_USER = self::BASE_URL . 'cgi-bin/tag/deltagusers?access_token=';
    const TAG_SEARCH = self::BASE_URL . 'cgi-bin/tag/list?access_token=';

}
